# -*- encoding: utf-8 -*- 
""" CZTrailery plugin module for www.cztrailery.cz """

__all__ = ['CZTraileryPlugin']

from lib.basePlugin import *
import re
import httplib


LINE_PREFIX = {
        'director'  : u'Režie:',
        'cast'      : u'Hrají:',
        'studio'    : u'Studio:',
    }

RE_KEYPARAM = re.compile(r'(?:["&]|&amp;)(file|captions\.file)=([^&"]+)')
RE_ADDVAR   = re.compile(r"addVariable\('(file|captions\.file)','([^']+)'\);")

RE_NJOY_URL = re.compile(r'^(http://n-joy\.cz/video/[^/]+/[^/]+)')
RE_NJOY_STREAM = re.compile(r'flashvars\.file_url\s*=\s*"([^"]+)"')

RE_YOUTUBE_URL = re.compile('^http://(?:\w+\.)youtube.com/(?:watch\?v=|v/)([\w-]+)')
RE_XML_FILE    = re.compile('^http://[^/]*cztrailery\.cz/.*\.xml$')
RE_YOUTUBE_T   = re.compile(r', "t": "([^"]+)"')

RE_SEVENLOAD_URL = re.compile(r'^http://(?:[^/]*)sevenload.com/pl/(\w+)/\d+x\d+/swf')

RE_ZIDEO_URL = re.compile(r'^http://zideo.nl/zideomediaplayer.php\?(.*)')


class CZTraileryPlugin(BasePlugin):
    LOGPREFIX = "[cztrailery plugin] "
    BASE_URL = "http://www.cztrailery.cz"
    SUBTITLES_XBMC_PATH = "special://userdata/cztrailery-subtitles.srt"

    @plugin_folder
    def root(self):
        """ plugin root folder """
        self.core.setSorting('NONE')
        yield PFolder(label=u'Nová videa', call='list')
        yield PFolder(label=u'Právě v kinech', call='list', 
                        param={'path': '/category/kino/'})
        yield PFolder(label=u'Kategorie', call='categories')
        yield PFolder(label=u'Podle abecedy', call='alphabet')
        #yield PFolder(label=u'Hledat', call='search')


    @plugin_folder
    def categories(self):
        """ Get list of categories from homepage """
        self.core.setSorting('NONE')
        self.wget.request(self.BASE_URL)
        for e in self.wget.select('div#tag_cloud a'):
            label = e.text + ' - ' + e['title']
            path = self.relative_path( e['href'] )
            yield PFolder(label=label, call='list', param={'path': path})


    @plugin_folder
    def alphabet(self):
        """ Get all videos alphabeticaly sorted """
        # list chars: 
        self.wget.request( self.BASE_URL + '/databaze-traileru/' )
        
        nextPages = self.wget.select('div.azpagelinks .azlink a')
        SELECTOR = 'div.azindex li > a'
        items = self.wget.select(SELECTOR)

        self.core.totalItems = len(items) * (1 + len(nextPages))

        while 1:
            # generate items from this page 
            for e in items:
                label = e.text
                path  = self.relative_path(e.get('href'))
                yield PFolder(label=label, call='play', param={'path': path})

            # load next page 
            if not nextPages:
                break

            pageLink = nextPages.pop(0)
            self.wget.request( pageLink.get('href') )
            items = self.wget.select(SELECTOR)


        # List chars: 
        #for e in self.wget.select('div.azlinks a'):
        #    path = self.relative_path(e.get('href'))
        #    yield PFolder(label=e.text_content(), call='alphabet_char',
        #                    param={'path': path})


    @plugin_folder
    def list(self, path='/'):
        """ list videos on home page """
        self.core.setSorting('NONE')
        self.wget.request( self.BASE_URL + path )
        for item in self.wget.select('#maincontent div.galleryitem'):
            h3_a = item.select_first('h3 a')
            param = {'path': self.relative_path(h3_a['href']) }
            yield PItem(label=h3_a.text, 
                        iconURL=item.select_first('img')['src'],
                        call='play', param=param)


    @plugin_call
    def play(self, path):
        """ play video """
        self.core.newProgress(u'Stahuji data pro přehrátí',
                                u'Stahuji informace o videu')

        # get video info 
        self.debug('play video url on path: '+repr(path))
        item = self.get_info(path)

        # get video parameters from page: 
        div_video = self.wget.select_first('div.video')
        if not div_video:
            raise Exception("'div.video' not found in path: "+repr(path))

        (streamURL, subtitlesURL) = self.get_video_params( div_video )

        if not streamURL:
            raise Exception("Video file URL not found in: "+repr(path)
                                + "\ndiv.video: " + repr(div_video))

        origStreamURL = streamURL
    
        # get video stream URL 
        self.core.updateProgress(30, 'Hledám URL video streamu', streamURL)

        if RE_XML_FILE.match( streamURL ):
            (streamURL, subtitlesURL) = self.parse_xml_file( streamURL, subtitlesURL )

        self.core.updateProgress(50, 'Hledám URL video streamu', streamURL)

        if RE_SEVENLOAD_URL.match( streamURL ):
            streamURL = self.get_sevenload_stream( streamURL )

        if RE_NJOY_URL.match( streamURL ):
            streamURL = self.get_njoy_stream( streamURL )
                
        if RE_ZIDEO_URL.match( streamURL ):
            streamURL = self.get_zideo_stream( streamURL )

        if RE_YOUTUBE_URL.match( streamURL ):
            streamURL = self.get_youtube_stream( streamURL )

        self.core.closeProgress()
        self.debug('streamURL: '+repr(streamURL))
        self.debug('subtitlesURL: '+repr(subtitlesURL))
        if streamURL:
            subtitles=None
            if subtitlesURL:
                self.core.updateProgress(80, 'Stahuji titulky', subtitlesURL)
                subtitles = self.download_subtitles( subtitlesURL )
            self.core.play(streamURL, item, subtitles)
        else:
            self.error('Cannot play video URL: ' + origStreamURL)
            self.core.okDialog('Cannot play video URL', origStreamURL)


    ### Internal methods ###

    def relative_path(self, path):
        if path.lower().startswith(self.BASE_URL.lower()):
            return path[len(self.BASE_URL):]
        return path


    def get_info(self, path):
        url = self.BASE_URL + path
        self.wget.request(url)

        content = self.wget.select('#maincontent')
        pList = [e.text.strip() for e in content.select('.postdets ~ p') ]
        outline = "\n\n".join( filter(None, pList) )

        postdets_p = content.select('.postdets > p')
        strong_tag = postdets_p.select('strong')
        info = {
                'genre': strong_tag[1].text.strip(),
                'plotoutline': outline,
            }
        for e in postdets_p:
            for key, prefix in LINE_PREFIX.items():
                if e.text and e.text.startswith(prefix):
                    info[key] = e.text[len(prefix):].strip()
        if info.has_key('cast'):
            info['cast'] = map(lambda s:s.strip(), info['cast'].split(','))

        return PItem(
                label   = content.select_first('h1').text,
                label2  = strong_tag[0].text,
                call    = 'play',
                param   = {'path': path},
                info    = info,
                iconURL = content.select_first('img.thumbnail')['src'],
            )


    def get_video_params(self, div_video):
        """ Parse div.video and return (streamURL, subtitlesURL) """
        div_video_text = unicode(div_video)
        attr = dict( RE_KEYPARAM.findall(div_video_text) )
        if not attr:
            attr = dict( RE_ADDVAR.findall(div_video_text) )

        # Parse video iframe
        if not attr:
            iframe = div_video.select_first('iframe')
            if iframe:
                attr['file'] = iframe['src']

        # Parse embed tag 
        if not attr.get('file'):
            embed = div_video.select_first('embed')
            if embed:
                attr['file'] = embed['src']

        # Parse object tag
        if not attr:
            object = div_video.select_first('object')
            if object:
                attr['file'] = object['data']
        
        return (attr.get('file'), attr.get('captions.file'))

        
    def get_youtube_stream(self, url):
        """ Get video stream URL """
        # get parameters  
        m = RE_YOUTUBE_URL.match(url)
        if not m:
            raise Exception("RE_YOUTUBE_URL not found!")
        id = m.group(1)

        self.wget.request( 'http://www.youtube.com/watch?v='+id )

        m = RE_YOUTUBE_T.search( self.wget.content )
        if not m:
            self.error("RE_YOUTUBE_T not found in: " + url)
            return None
        t = m.group(1)

        # Get video redirection 
        #url2 = "http://www.youtube.com/get_video?video_id=%s&t=%s" % (id, t)
        self.core.updateProgress(50, 'Get youtube redirection')
        conn = httplib.HTTPConnection("www.youtube.com")
        conn.request("HEAD", "/get_video?video_id=%s&t=%s" % (id, t))
        resp = conn.getresponse()

        return resp.getheader('Location')


    def get_njoy_stream(self, url):
        """ Get video streamURL from n-joy.cz """
        m = RE_NJOY_URL.match( url )
        baseURL = m.group(0)
        self.wget.request( baseURL )
        m = RE_NJOY_STREAM.search( self.wget.content )
        if m:
            return m.group(1)
        else:
            raise Exception('RE_NJOY_STREAM not found in: ' + baseURL)


    def get_zideo_stream(self, url):
        """ Get video stream URL from zideo.nl """
        m = RE_ZIDEO_URL.match( url )
        playlistURL = 'http://zideo.nl/media.php?' + m.group(1)

        self.wget.request( playlistURL )
        location = self.wget.select_first('location')
        if not location:
            raise Exception('Stream URL not found in: ' + playlistURL \
                                + "\nContent: " + repr(self.wget.content) )
        return location.text


    def get_sevenload_stream(self, url):
        """ Get video stream URL from sevenload.com page """

        m = RE_SEVENLOAD_URL.match( url )
        configURL = 'http://flash.sevenload.com/player?itemId=' + m.group(1)
        self.wget.request( configURL )

        location = self.wget.select_first('stream[quality=high] location') \
                    or self.select_first('stream[quality=normal] location') \
                    or self.select_first('stream location')
        if not location:
            raise Exception('Stream URL not found in: ' + url \
                                + "\nContent: " + repr(self.wget.content) )
        return location.text


    def download_subtitles(self, url):
        """ Download subtitles """
        fpath = self.core.translatePath( self.SUBTITLES_XBMC_PATH )
        self.debug('Downloading %r to %r' % (url, fpath))
        self.wget.request(url)
        fd = open(fpath, 'w')
        fd.write( self.wget.content )
        fd.close()
        return fpath


    def parse_xml_file(self, file_url, subtitlesURL=None):
        """ Download and parse XML file """
        self.wget.request(file_url)
        streamURL = self.wget.soup.find('location').text
        captions_tag = self.wget.soup.find('jwplayer:captions.file')
        if captions_tag:
            subtitlesURL = captions_tag.text
        return (streamURL, subtitlesURL)


